﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModeloGaleriaNET.VendedorArteCommands;
using System.Windows.Controls;
using ModeloGaleriaNET.Police;
using Newtonsoft.Json;
using ModeloGaleriaNET.VendedorArteCommands_Safe;

namespace ModeloGaleriaNET
{

    public class MessageCrearSubasta: IMessageType
    {
        private VendedorArteCommands.VendedorArteCommands vendedor;
        private Subasta subasta;
        private VendedorArteCommands.AuthInfo auth;
        private AvalonDock.DockableContent doc;
        private int usuarioId;
        private GandalfService policia;

        public MessageCrearSubasta(Subasta s, AvalonDock.DockableContent d, int uId)
        {
            doc = d;
            vendedor = new VendedorArteCommands.VendedorArteCommands();
            vendedor.Timeout = (int)ServerConnData.Instance.TimeOut*1000;
            auth = new AuthInfo();
            auth.pseudonimo = ServerConnData.Instance.User;
            auth.password = Utilities.EncriptarMD5(ServerConnData.Instance.Password);
            subasta = s;
            policia = new GandalfService();
            this.usuarioId = uId;
        }

        public Subasta Subasta
        {
            get { return subasta; }
        }

        public int UsuarioId
        {
            get { return usuarioId; }
        }
        
        public int Execute()
        {
            long salida = -1;
            int negociado, estado = -1;
            bool returnSpecified;
            string[] tematicas;
            List<Tematica> temas;
            authInfo authPolice;
            getTicketResponse ticketResponse;
            AESCripto aes;
            dynamic objeto;
            Dictionary<string, object> diccionarioFecha, diccionarioFin;
            string json, jsonRespuesta;
            byte[] encriptado, respuesta;
            VendedorArteCommandsService vendedorSafe;
            ticketEncryptedRequest request;
            obra obra;

            diccionarioFecha = new Dictionary<string, object>();
            diccionarioFin = new Dictionary<string,object>();
            temas = subasta.Tematicas.ToList();
            tematicas = new string[temas.Count];
            for (int i = temas.Count - 1; i >= 0; i--)
                tematicas[i] = temas[i].Nombre;

            switch (subasta.EstadoObra)
            {
                case "original":
                    estado = 0;
                    break;
                case "deteriorado":
                    estado = 1;
                    break;
                case "restaurado":
                    estado = 2;
                    break;
            }

            returnSpecified = true;
            negociado = subasta.TipoNegociado == "manual" ? 0 : 1;

            if (ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 || ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 3)
            {
                diccionarioFecha.Add("year", subasta.FechaInicio.Year);
                diccionarioFecha.Add("month", subasta.FechaInicio.Month - 1);
                diccionarioFecha.Add("dayOfMonth", subasta.FechaInicio.Day);
                diccionarioFecha.Add("hourOfDay", subasta.FechaInicio.Hour);
                diccionarioFecha.Add("minute", subasta.FechaInicio.Minute);
                diccionarioFecha.Add("second", subasta.FechaInicio.Second);
                diccionarioFecha.Add("zone", "GMT");

                diccionarioFin.Add("year", subasta.FechaLimite.Year);
                diccionarioFin.Add("month", subasta.FechaLimite.Month - 1);
                diccionarioFin.Add("dayOfMonth", subasta.FechaLimite.Day);
                diccionarioFin.Add("hourOfDay", subasta.FechaLimite.Hour);
                diccionarioFin.Add("minute", subasta.FechaLimite.Minute);
                diccionarioFin.Add("second", subasta.FechaLimite.Second);
                diccionarioFin.Add("zone", "GMT");

                obra = new VendedorArteCommands_Safe.obra();
                obra.año = (short)subasta.AnyoObra;
                obra.autor = subasta.AutorObra;
                obra.estadoConservacion = estado;
                obra.titulo = subasta.NombreObra;
                
                objeto = new
                {
                    comienza = diccionarioFecha,
                    finaliza = diccionarioFin,
                    mpp = subasta.MaximoPujasPostor,
                    obra = obra,
                    precioPartida = subasta.PrecioPartida,
                    referenciaCliente = subasta.Id.ToString(),
                    tematicas = tematicas
                };
                json = JsonConvert.SerializeObject(objeto);

                policia.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 ?
                   ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_Police_GandalfService :
                   ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_Police_GandalfService_SSL;
                policia.Timeout = (int)ModeloGaleriaNET.Properties.Settings.Default.TimeOut * 1000;
                authPolice = new authInfo();
                authPolice.pseudonimo = ServerConnData.Instance.User;
                authPolice.password = Utilities.EncriptarMD5(ServerConnData.Instance.Password);
                ticketResponse = policia.getTicket(authPolice);

                // Crear mensaje encriptado con el JSON y enviar
                aes = new ModeloGaleriaNET.AESCripto(ticketResponse.secretKey);
                encriptado = aes.EncryptStringToBytes(json);
            
                vendedorSafe = new VendedorArteCommandsService();
                vendedorSafe.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 ?
                    ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_VendedorArteCommands_Safe_VendedorArteCommandsService :
                    ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_VendedorArteCommands_Safe_VendedorArteCommandsService_SSL;
                vendedorSafe.Timeout = (int)ModeloGaleriaNET.Properties.Settings.Default.TimeOut * 1000;
                request = new VendedorArteCommands_Safe.ticketEncryptedRequest();
                request.message = encriptado;
                request.ticketId = ticketResponse.ticketId;
                respuesta = vendedorSafe.publicarSubastaEncrypted(request);
                jsonRespuesta = aes.DecryptStringFromBytes(respuesta);
                salida = Convert.ToInt64(jsonRespuesta);
            }
            else
            {
                vendedor.Url = Properties.Settings.Default.Seguridad == 0 ?
                    Properties.Settings.Default.ModeloGaleriaNET_VendedorArteCommands_VendedorArteCommands :
                    Properties.Settings.Default.ModeloGaleriaNET_VendedorArteCommands_VendedorArteCommands_SSL;
                vendedor.publicar(auth, subasta.Id.ToString(), negociado, true, TimeZoneInfo.ConvertTime(subasta.FechaInicio, TimeZoneInfo.Utc), true, TimeZoneInfo.ConvertTime(subasta.FechaLimite, TimeZoneInfo.Utc), true, subasta.PrecioPartida, true,
                    subasta.MaximoPujasPostor, true, subasta.NombreObra, subasta.AutorObra, (short)subasta.AnyoObra, true, estado,
                    true, tematicas, out salida, out returnSpecified);    
            }

            System.Threading.Thread.Sleep(1500);
            return (int)salida;
        }

        public void printInitialMessage()
        {
            Utilities.WriteMessageOnGrid(doc, "[Local]\tCreando la subasta con referencia local " + subasta.Id + " en el servidor...",
                DataGridMessage.TIPO_MENSAJE.INFO);
        }

        public void printErrorMessage()
        {
            Utilities.WriteMessageOnGrid(doc, "[Local]\tHa ocurrido un error al crear la subasta con referencia local " + subasta.Id + " en el servidor",
                DataGridMessage.TIPO_MENSAJE.WARNING);
        }

        public void printLastErrorMessage()
        {
            Utilities.WriteMessageOnGrid(doc, "[Local]\tNo se ha podido crear la subasta con referencia "
                    + subasta.Id + " en el servidor después de 3 intentos. Se han desecho los cambios en local",
                DataGridMessage.TIPO_MENSAJE.ERROR);
        }

        public void printSuccessMessage()
        {
            Utilities.WriteMessageOnGrid(doc, "[Local]\tLa subasta con referencia "
                    + subasta.Id + " se ha creado en el servidor con referencia " + subasta.ReferenciaExterna, 
                DataGridMessage.TIPO_MENSAJE.INFO);
        }
    }
}
